package xyz.thoughtset.viewer.ai.mcp.client.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.util.StringUtils;
import xyz.thoughtset.viewer.common.core.entity.BaseMeta;
import xyz.thoughtset.viewer.common.crud.core.annotation.ApiCRUDPower;

import java.net.http.HttpClient;
import java.time.Duration;

@TableName
@Data
@AllArgsConstructor
@ApiCRUDPower(insert = false,save = true,update = false,list = true)
public class McpBotInfo extends BaseMeta {
    protected Integer typeCode = 11;//SSE
    protected String version;
    protected String serverTitle;
    protected String baseUrl;
    protected String sseEndpoint;
    protected Integer requestTimeout;
    protected Integer connectTimeout;

    protected String disableToolNames;

    protected String headers;


    public McpBotInfo() {
        this.statesCode = null;
    }

    public McpBotInfo(String serverId, Integer runningCode) {
        this();
        this.id = serverId;
        this.statesCode = runningCode;
    }

    public McpClientLink buildClientLink(ObjectMapper objectMapper){
        String sseEndpoint = StringUtils.hasText(this.sseEndpoint) ? this.sseEndpoint : "/sse";
        HttpClientSseClientTransport.Builder transportBuilder = HttpClientSseClientTransport.builder(baseUrl)
                .sseEndpoint(sseEndpoint)
                .connectTimeout(Duration.ofSeconds(this.connectTimeout!= null ? this.connectTimeout : 10))
                .clientBuilder(HttpClient.newBuilder())
                .objectMapper(objectMapper);
        HttpClientSseClientTransport transport = transportBuilder.build();
        McpSchema.Implementation clientInfo = new McpSchema.Implementation(
                this.title,
                version);
        McpClient.SyncSpec spec = McpClient.sync(transport)
                .clientInfo(clientInfo)
                .requestTimeout(Duration.ofSeconds(this.requestTimeout!= null ? this.requestTimeout : 20));
        //todo headers
        //todo spec.toolsChangeConsumer()
//        var client = spec.build();
//        McpSchema.InitializeResult result = client.initialize();
        return McpClientLink.builder()
                .clientInfo(this)
                .spec(spec)
                .build();
    }

}
